<template>
	<div>
		<el-tabs v-model="activeName">
			<el-tab-pane label="地图" name="first">地图</el-tab-pane>
			<el-tab-pane label="路线" name="second">路线</el-tab-pane>
			<el-tab-pane label="百度" name="third">百度</el-tab-pane>
		</el-tabs>
		<div v-if="activeName == 'first'">
			<div style="margin-top: 30px;position: relative;">
				<div ref="map" style="width: 100%;height:600px;"></div>
				<button @click="changeActStatusOfpoints(false, '244,244,244')">changeActStatusOfpoints</button>
				<button @click="lineCurveness(),lineAnimate(0)">lineCurveness</button>
				<button @click="lineAnimate(0)">lineAnimate</button>
				<button @click="line()">line line</button>
				<button @click="drawer = true">open draw</button>
				<el-drawer ref="drawer" title="我是标题" :visible.sync="drawer" :direction="direction"
					:modal-append-to-body="false">
					<span @click="drawer = false">我来啦!</span>
				</el-drawer>
			</div>
		</div>
		<div v-if="activeName == 'second'">
			<polyline-decorator></polyline-decorator>
		</div>
		<div v-if="activeName == 'third'">
			百度地图
			<baidu-map-first></baidu-map-first>
		</div>
	</div>
</template>

<script>
	import mapboxgl from 'mapbox-gl';
	import * as turf from '@turf/turf';
	export default {
		name: "map",
		data() {
			return {
				activeName: 'first',
				localeIszh: true,
				drawer: false,
				direction: 'rtl',
				animiColor: '56, 159, 255',
				map: {},
				resp: [],
				mapToken: 'pk.eyJ1IjoibGVpeXV5YW4iLCJhIjoiY2trZzltajd6MGhsMDJvcW43bHBna3c2biJ9.OE_79L9HaZAe6nnr8VYLTA'
			}
		},
		created() {
			this.resp = [{
				departureCode: 'BJS',
				departureName: '北京',
				departureLongitude: 116.4333333,
				departureLatitude: 39.91944438,
				destinationCode: 'SHA',
				destinationName: '上海',
				destinationLongitude: 121.3666666,
				destinationLatitude: 31.1,
				animiColor: '56, 159, 255'
			}, {
				departureCode: 'LON',
				departureName: '伦敦',
				departureLongitude: -0.16666667,
				departureLatitude: 51.5,
				destinationCode: 'SHA',
				destinationName: '上海',
				destinationLongitude: 121.3666666,
				destinationLatitude: 31.1,
				animiColor: '56, 159, 255'
			}, {
				departureCode: 'NYC',
				departureName: '纽约',
				departureLongitude: -73.99416667,
				departureLatitude: 39.91944438,
				destinationCode: 'SHA',
				destinationName: '北京',
				destinationLongitude: 116.4333333,
				destinationLatitude: 40.75166667,
				animiColor: '56, 159, 255'
			}, {
				departureCode: 'CTU',
				departureName: '成都',
				departureLongitude: 101.3651,
				departureLatitude: 32.6545,
				destinationCode: 'XIY',
				destinationName: '西安',
				destinationLongitude: 108.3666666,
				destinationLatitude: 35.1,
				animiColor: '56, 159, 255'
			}]
		},
		components: {
			'polyline-decorator': () => import('../components/PolylineDecorator.vue'),
			'baidu-map-first': () => import('../components/BaiduMapFirst.vue')
		},
		mounted() {
			this.$nextTick(() => {
				this.init();
			})
		},
		methods: {
			handleClose() {

			},
			init() {
				mapboxgl.accessToken = this.mapToken;
				const map = new mapboxgl.Map({
					container: this.$refs.map,
					style: 'mapbox://styles/mapbox/dark-v10',
					center: [109.05257932529969, 34.341575935317664],
					zoom: 4,
					attributionControl: false
				});
				this.map = map;
				map.on('load', () => {
					this.initMapPoints();
					var svgXML =
						`<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> 
					                <path d="M529.6128 512L239.9232 222.4128 384.7168 77.5168 819.2 512 384.7168 946.4832 239.9232 801.5872z" p-id="9085" fill="#ffffff"></path> 
					            </svg>`;
					var svgBase64 = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(
						svgXML)));
					let planeBase64 =
						'';
					let arrowIcon = new Image(50, 50)
					arrowIcon.src = planeBase64
					arrowIcon.onload = function() {
						map.addImage('arrowIcon', arrowIcon);
					}
					// //鼠标移入形状
					// map.on('mouseenter', 'points', function() {
					// 	map.getCanvas().style.cursor = 'pointer';
					// });
					// map.on('mouseleave', 'points', function() {
					// 	map.getCanvas().style.cursor = '';
					// });
					// map.on('click', 'points', (e) => {
					// 	this.changeActStatusOfpoints(true, '25,89,75');
					// 	this.line(e);
					// 	console.log('e', e.features);
					// });
					map.on('mouseenter', 'points', (e) => {
						console.log('e', e);
						map.getCanvas().style.cursor = 'pointer';
						this.changeActStatusOfpoints(true, '218, 66, 255');
					});
					map.on('mouseleave', 'points', (e) => {
						map.getCanvas().style.cursor = '';
						this.changeActStatusOfpoints(true, '17, 71, 141')
					});
					map.on('click', 'points', (e) => {
						//this.changeActStatusOfpoints(true, '25,89,75');
						//this.line(e);
						//this.lineAnimate();
						this.line(e);
						this.changeActStatusOfpoints(true, '218, 66, 255');
						console.log('e', e.features);
					});
					map.on('mouseenter', 'route', (e) => {
						console.log('mouseenter', e);
						map.getCanvas().style.cursor = 'pointer';
						this.changeActStatusOfLine(true, 'CTUline');
						//this.changeActStatusOfLine(false,e.features[0].id);
					});
					map.on('mouseleave', 'route', (e) => {
						map.getCanvas().style.cursor = '';
						this.changeActStatusOfLine(false, 'CTUline');
					});
					map.on('click', 'route', (e) => {
						//this.changeActStatusOfpoints(true, '25,89,75');
						//this.line(e);
						//this.lineAnimate();
						this.changeActStatusOfLine(true, e.features[0].id);
						console.log('e', e.features);
					});
					map.on('mouseenter', 'route5', (e) => {
						console.log('mouseenter', e);
						this.animiColor = '218, 66, 255';
						let obj = this.resp.find(item => item.departureCode + '-' + item.destinationCode ==
							e.features[0].id);
						!!obj && (obj.animiColor = '218, 66, 255');
						map.getCanvas().style.cursor = 'pointer';
						this.changeActStatusOfLine(true, this.id = e.features[0].id);
					});
					map.on('mouseleave', 'route5', (e) => {
						console.log('mouseleave', e);
						this.animiColor = '56, 159, 255';
						let obj = this.resp.find(item => item.departureCode + '-' + item.destinationCode ==
							this.id);
						!!obj && (obj.animiColor = '56, 159, 255');
						map.getCanvas().style.cursor = '';
						this.changeActStatusOfLine(false, this.id)
					});
					map.on('click', 'route5', (e) => {
						//this.changeActStatusOfpoints(true, '25,89,75');
						//this.line(e);
						//this.lineAnimate();
						this.changeActStatusOfLine(false, 'AL001');
						console.log('e', e.features);
					});
				});
			},
			initMapPoints() {
				//为地图添加数据源
				let noActiveCircleColorRgba = '17, 71, 141';
				var sources = {
					'type': 'geojson',
					'promoteId': 'id',
					'data': {
						'type': 'FeatureCollection',
						"bbox": [-180.0, -90.0, 180.0, 90.0],
						'generateId': true,
						'features': []
					}
				};
				for (let item of this.resp) {
					sources.data.features.push({
						'type': 'Feature',
						'promoteId': 'title',
						'geometry': {
							'type': 'Point',
							'coordinates': [item.departureLongitude, item.departureLatitude]
						},
						'properties': {
							'id': item.departureCode,
							'title': item.departureName,
							'titleEn': item.departureName
						}
					});
					sources.data.features.push({
						'type': 'Feature',
						'promoteId': 'title',
						'geometry': {
							'type': 'Point',
							'coordinates': [item.destinationLongitude, item.destinationLatitude]
						},
						'properties': {
							'id': item.destinationCode,
							'title': item.destinationName,
							'titleEn': item.destinationName
						}
					});
				}
				this.map.addSource('points', sources);
				this.map.addLayer({
					'id': 'points',
					'source': 'points',
					'type': 'circle',
					'paint': {
						'circle-radius': 1,
						'circle-color': ["case", ["boolean", ['feature-state', 'circle-status'], false],
							['concat', ['concat', 'rgba(', ['feature-state', 'circle-color']], ',1)'],
							`rgba(${noActiveCircleColorRgba},1)`
						],
						'circle-stroke-width': 1,
						'circle-stroke-color': ["case", ["boolean", ['feature-state', 'circle-status'], false],
							['concat', ['concat', 'rgba(', ['feature-state', 'circle-color']], ',0.2)'],
							`rgba(${noActiveCircleColorRgba},0.2)`
						],
					}
				});

				this.map.addLayer({
					id: 'cluster-count',
					type: 'symbol',
					source: 'points',
					layout: {
						'text-field': ["case", ["boolean", this.localeIszh, false],
							['get', 'title'],
							['get', 'titleEn']
						],
						'text-font': ['DIN Offc Pro Medium'],
						'text-size': 11,
						'text-offset': [0, -1.3]
					},
					paint: {
						'text-color': ["case", ["boolean", ['feature-state', 'circle-status'], false],
							['concat', ['concat', 'rgba(', ['feature-state', 'circle-color']], ',1)'],
							`rgba(${noActiveCircleColorRgba},1)`
						]
					}
				});
			},
			line(point) {
				let noActiveCircleColorRgba = '136, 136, 136';
				//var pointFeature = point.features[0];
				var routeLines = {
					'type': 'FeatureCollection',
					"bbox": [-180.0, -90.0, 180.0, 90.0]
					//'features': []
				};
				let line = turf.lineString([
					[108.091308, 38.427501],
					[108.695556, 38.729501],
					[108.552734, 39.40443],
					[106.61914, 39.134789],
					[105.652343, 40.07657],
					[105.157958, 40.210656]
				]);
				let getControl = (start, end, c) => {
					let control = [
						(start[0] + end[0]) / 2 - (start[1] - end[1]) * c,
						(start[1] + end[1]) / 2 - (end[0] - start[0]) * c
					]
					return control
				}
				let start = [121, 48];
				let end = [90, 35];
				let p2 = getControl(start, end, 0.2);
				line = turf.lineString([
					start,
					p2,
					end
				]);
				let arcData = turf.bezierSpline(line, {
					sharpness: 0.85
				});
				// arcData = turf.greatCircle(turf.point([121, 48]), turf.point([90, 35]), {
				// 	properties: {
				// 		name: 'Seattle to DC'
				// 	},
				// 	offset: 1
				// })
				//routeLines.features[0] = arcData;
				//routeLines.features[0].properties.id = pointFeature.properties.id + 'line';
				let buildLines = function(start, end) {
					var features = [];
					var curveness = 0.3;
					var control = [
						(start[0] + end[0]) / 2 - (start[1] - end[1]) * curveness,
						(start[1] + end[1]) / 2 - (end[0] - start[0]) * curveness
					];

					var t = 0;
					var points = [];
					while (t < 1) {
						t += 0.001;
						var x = Math.pow((1 - t), 2) * start[0] + 2 * t * (1 - t) * control[0] + Math.pow(t, 2) * end[
							0];
						var y = Math.pow((1 - t), 2) * start[1] + 2 * t * (1 - t) * control[1] + Math.pow(t, 2) * end[
							1];

						points.push([x, y]);
					}
					// features.push({
					//   "type": "Feature",
					//   "geometry": {
					//     "type": "LineString",
					//     "coordinates": points,
					//   },
					//   "properties": {
					//     //"color": `rgba(${noActiveCircleColorRgba}, 1)`
					//   },
					// });
					// return features;
					return points;
				}
				//routeLines.features = buildLines(start, end);
				routeLines.geometry = {
					type: "LineString",
					coordinates: [start, end]
				}
				// this.map.addSource('routeLines', {
				// 	'type': 'geojson',
				// 	'promoteId': 'id',
				// 	'data': routeLines
				// });
				this.map.addLayer({
					id: 'route',
					type: 'line',
					source: {
						'type': 'geojson',
						//'promoteId': 'id',
						'data': {
							type: "Feature",
							properties: {},
							geometry: {
								type: "LineString",
								coordinates: buildLines(start, end),
							}
						}
					},
					layout: {
						'line-join': 'round',
						'line-cap': 'round'
					},
					paint: {
						'line-width': 8,
						'line-color': "#888"
					}
				});
				this.map.addLayer({
					'id': 'arrowLayer',
					'type': 'symbol',
					'source': {
						'type': 'geojson',
						//'promoteId': 'id',
						'data': {
							type: "Feature",
							properties: {
								offset: [50, 50],
								bearing: turf.bearing(buildLines(start, end)[498], buildLines(start, end)[500]) -
									90
							},
							geometry: {
								type: "Point",
								coordinates: buildLines(start, end)[499],
							}
						}
					},
					'layout': {
						//'symbol-placement': 'line',
						//'symbol-spacing': 50, // 图标间隔，默认为250
						'icon-image': 'arrowIcon', //箭头图标
						'icon-size': 0.5,
						"icon-rotate": ["get", "bearing"],
						"icon-offset": ["get", "offset"],
						"icon-rotation-alignment": "map",
						"icon-allow-overlap": true,
						"icon-ignore-placement": true
					}
				});
				console.log('rote', turf.bearing(buildLines(start, end)[498], buildLines(start, end)[501]))
			},
			lineCurveness() {
				let noActiveCircleColorRgba = '17, 71, 141';
				// let lines = buildLines([parseFloat('108.3666666'), parseFloat('35.1')], [
				// 	[parseFloat('121.3666666'), parseFloat('31.1')]
				// ]);
				let lines = buildLines(this.resp);
				// 添加数据源
				this.map.addSource("chart-lines", {
					"type": "geojson",
					'promoteId': 'id',
					/* geojson类型资源 */
					"data": {
						/* geojson数据 */
						"type": "FeatureCollection",
						"features": lines
					}
				});

				this.map.addLayer({
					"id": "route5",
					"type": "line",
					"source": "chart-lines",
					"layout": {
						"line-join": "round",
						"line-cap": "round"
					},
					"paint": {
						//"line-color": ["get", "color"],
						"line-color": ["case", ["boolean", ['feature-state', 'line-status'], false],
							['concat', ['concat', 'rgba(', ['feature-state', 'line-color']], ',1)'],
							`rgba(${noActiveCircleColorRgba},1)`
						],
						"line-width": 2
					}
				});
				// this.map.addLayer({
				// 	'id': 'arrowLayer1',
				// 	'type': 'symbol',
				// 	'source': 'chart-lines',
				// 	'layout': {
				// 		'symbol-placement': 'line',
				// 		'symbol-spacing': 50, // 图标间隔，默认为250
				// 		'icon-image': 'arrowIcon', //箭头图标
				// 		'icon-size': 0.5
				// 	}
				// });

				function buildLines(resp) {
					var features = [];
					var curveness = 0.3;
					for (let item of resp) {
						var start = [item.departureLongitude, item.departureLatitude];
						var end = [item.destinationLongitude, item.destinationLatitude];
						var control = [
							(start[0] + end[0]) / 2 - (start[1] - end[1]) * curveness,
							(start[1] + end[1]) / 2 - (end[0] - start[0]) * curveness
						];

						var t = 0;
						var points = [];
						while (t < 1) {
							t += 0.001;
							var x = Math.pow((1 - t), 2) * start[0] + 2 * t * (1 - t) * control[0] + Math.pow(t, 2) * end[
								0];
							var y = Math.pow((1 - t), 2) * start[1] + 2 * t * (1 - t) * control[1] + Math.pow(t, 2) * end[
								1];

							points.push([x, y]);
						}
						features.push({
							"type": "Feature",
							"geometry": {
								"type": "LineString",
								"coordinates": points,
							},
							"properties": {
								'id': item.departureCode + '-' + item.destinationCode
								//"color": `rgba(${noActiveCircleColorRgba}, 1)`
							},
						});
					}
					return features;
				}
			},
			lineAnimate(t) {
				let noActiveCircleColorRgba = this.animiColor;
				// let lines = buildPoints([parseFloat('108.3666666'), parseFloat('35.1')], [
				// 	[parseFloat('121.3666666'), parseFloat('31.1')]
				// ], t);
				let lines = buildPoints(this.resp, t);
				//console.log(lines);
				//console.log('t++++++++++',t);
				if (!!!this.map.getLayer("achart-pointss")) {
					this.map.addSource("achart-points", {
						"type": "geojson",
						/* geojson类型资源 */
						"data": {
							/* geojson数据 */
							"type": "FeatureCollection",
							"features": lines
						}
					});
					this.map.addLayer({
						"id": "achart-pointss",
						"type": "circle",
						/* circle类型表示一个圆，一般比较小 */
						"source": "achart-points",
						"paint": {
							"circle-radius": ["get", "radius"],
							"circle-color": ["get", "color"],
							/* 圆的颜色 */
							"circle-stroke-width": 1,
							/* 边框宽度 */
							"circle-stroke-color": ["get", "color"],
							/* 边框的颜色 */
							"circle-opacity": 0.5,
							"circle-pitch-alignment": "map"
						}
					});
				} else {
					this.map.getSource('achart-points').setData({
						/* geojson数据 */
						"type": "FeatureCollection",
						"features": lines
					});
				}
				setTimeout(() => {

					t > 1 ? this.lineAnimate(0) : this.lineAnimate(t + 0.001);
				}, 10)
				//requestAnimationFrame(this.lineAnimate)
				function buildPoints(resp, time) {
					var features = [];
					var curveness = 0.3;
					for (let item of resp) {
						var start = [item.departureLongitude, item.departureLatitude];
						var end = [item.destinationLongitude, item.destinationLatitude];
						var control = [
							(start[0] + end[0]) / 2 - (start[1] - end[1]) * curveness,
							(start[1] + end[1]) / 2 - (end[0] - start[0]) * curveness
						];

						// 为了绘制彗星尾迹，需要同时画出count个半径递增的圆点
						var count = 50;
						// 最大圆点的半径
						var maxRadius = 1;
						// 求出当前时间点小圆点的坐标
						var t = time;
						let points = [];
						for (var j = 0; j < count; j++) {
							t += 0.001;
							if (t > 1) break;
							var x = Math.pow((1 - t), 2) * start[0] + 2 * t * (1 - t) * control[0] + Math.pow(t, 2) * end[
								0];
							var y = Math.pow((1 - t), 2) * start[1] + 2 * t * (1 - t) * control[1] + Math.pow(t, 2) * end[
								1];

							points.push([x, y]);
							features.push({
								"type": "Feature",
								"geometry": {
									"type": "Point",
									"coordinates": [x, y],
								},
								"properties": {
									//"radius": maxRadius * j / count,
									"radius": maxRadius,
									"color": `rgba(${item.animiColor}, 1)`
								},
							});
						}
						// features.push({
						// 	"type": "Feature",
						// 	"geometry": {
						// 		"type": "LineString",
						// 		"coordinates": points,
						// 	},
						// 	"properties": {
						// 		"color": `rgba(${noActiveCircleColorRgba}, 1)`
						// 	},
						// });
					}
					return features;
				}
			},
			changeActStatusOfpoints(status, color) {
				this.map.setFeatureState({
					'source': 'points',
					id: 'CTU'
				}, {
					'circle-color': color,
					'circle-status': status,
				});
			},
			changeActStatusOfLine(status, id) {
				let lineColorRgba = status ? '94,36,118' : '17, 71, 141';
				this.map.setFeatureState({
					'source': 'chart-lines',
					//'source': 'routeLines',
					id: id
				}, {
					'line-color': lineColorRgba,
					'line-status': status,
				});
				console.log(lineColorRgba, id)
				/*this.map.setFeatureState({
					'source': 'chart-lines',
					id: 'AL001'
				}, {
					'circle-color': circleColorRgba,
					'circle-status': status,
				});*/
			}
		}
	}
</script>

<style>
	::v-deep .el-drawer__wrapper {
		position: absolute !important;
		top: 0;
		right: 0;
		left: unset !important;
		bottom: 0;
		overflow: hidden;
		margin: 0;
		width: 580px;
	}
</style>
